package gouroutine_pool

import (
	"fmt"
	"sync/atomic"
	"test/tools"
	"time"
)

var ticket int32 = 1000
var sum int64 = 0

// go携程池
func main() {
	// 记录耗时
	defer tools.TimeSpend("main")()

	//pool := p.NewDefaultGoroutinePool(runtime.NumCPU())   // 创建携程池，大小与系统核心数相同
	pool := NewDefaultGoroutinePool(20) // 创建携程池，大小与系统核心数相同
	//pool := NewFactoryPool(runtime.NumCPU(),&DefaultTaskFactory{},&DefaultRejectStrategy{})   // 创建携程池，大小与系统核心数相同
	pool.Init()

	// 模拟写入任务
	go func() {
		for atomic.LoadInt32(&ticket) >= 0 {
			if atomic.LoadInt32(&ticket) == 0 {
				// 任务完成后关闭池
				pool.Close()
				break
			}
			atomic.AddInt32(&ticket, -1)

			// 模拟卖票

			// 使用默认方式
			t := NewTask(sell, ticket, 1, time.Second, callBack, "sell")
			err := pool.AddTask(t)

			// 使用工厂方法
			//err:= pool.addTaskByFactory(sell,ticket,0,0,nil,"main")

			if err != nil {
				fmt.Println("add task failed, error msg:", err)
			}
		}
	}()

	// 等待所有任务完成
	_, closed := <-*pool.StopChan()
	if closed {
		printTask(pool)

		fmt.Println("sum", sum) // 测试并发
		fmt.Println("main over")
	}
}

// 模拟买票的方法
func sell(args interface{}) (interface{}, error) {
	atomic.AddInt64(&sum, 1)
	return args, nil
}

// 模拟回调方法
func callBack(args interface{}) (interface{}, error) {
	fmt.Println("call callback method !")
	return args, nil
}

// 打印已经完成的任务
func printTask(pool *GoroutinePool) {
	res := pool.CompleteTask()
	for _, v := range res {
		fmt.Println(v)
	}
}
